import pygame, cPickle, socket

class event_handler:
    def __init__(self, game):
        self.game = game
        self.game_logic = self.game.game_logic
        self.event_bindings = {}
        
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sock.bind(("", 1976))
        self.sock.settimeout(5)
    
    def run(self):
        for ev in self.game.events:
            if not self.event_bindings.has_key(ev.type):
                return
            
            for callback in self.event_bindings[ev.type]:
                callback(ev)
        """
            if ev.type == pygame.QUIT:
                self.game.main_loop = False
            elif ev.type == pygame.KEYDOWN and ev.key == pygame.K_a:
                self.send_user_event("rot_left", self.game_logic.local_player)
                self.game_logic.local_player.tank.rotate_left()
            elif ev.type == pygame.KEYDOWN and ev.key == pygame.K_d:
                self.send_user_event("rot_right", self.game_logic.local_player)
                self.game_logic.local_player.tank.rotate_right()
            elif ev.type == pygame.KEYDOWN and ev.key == pygame.K_w and self.game_logic.local_player.tank.speed == 0:
                self.send_user_event("forward", self.game_logic.local_player)
                self.game_logic.local_player.tank.forward()
            elif ev.type == pygame.KEYUP and ev.key == pygame.K_w:
                self.send_user_event("stop", self.game_logic.local_player)
                self.game_logic.local_player.tank.stop()
            elif ev.type == pygame.KEYDOWN and ev.key == pygame.K_s and self.game_logic.local_player.tank.speed == 0:
                self.send_user_event("reverse", self.game_logic.local_player)
                self.game_logic.local_player.tank.reverse()
            elif ev.type == pygame.KEYUP and ev.key == pygame.K_s:
                self.send_user_event("stop", self.game_logic.local_player)
                self.game_logic.local_player.tank.stop()
            elif ev.type == pygame.MOUSEBUTTONDOWN:
                if ev.button == 1:
                    self.send_user_event("shoot", self.game_logic.local_player, {'target': self.game_logic.aimer.rect.center})
                    self.game_logic.local_player.tank.shoot(self.game_logic.aimer.rect.center)
                elif ev.button == 3:
                    self.game_logic.local_player.tank.hit(5, 0)
            elif ev.type == pygame.USEREVENT:
                if ev.details['id'] == self.game_logic.local_player.player_id and not ev.details['from_host']:
                    self.user_events.append(ev.details)
                else:
                    if self.game.config.host == True:
                        self.user_events.append(ev.details)
                if ev.details['type'] == "rot_left":
                    if ev.details['id'] == self.game_logic.local_player.player_id:
                        continue
                    self.game.players[ev.details['id']].tank.set_pos(ev.details['pos'])
                    self.game.players[ev.details['id']].tank.set_rot(ev.details['rot'])
                    self.game.players[ev.details['id']].tank.rotate_left()
                elif ev.details['type'] == "rot_right":
                    if ev.details['id'] == self.game_logic.local_player.player_id:
                        continue
                    self.game.players[ev.details['id']].tank.set_pos(ev.details['pos'])
                    self.game.players[ev.details['id']].tank.set_rot(ev.details['rot'])
                    self.game.players[ev.details['id']].tank.rotate_right()
                elif ev.details['type'] == "forward":
                    if ev.details['id'] == self.game_logic.local_player.player_id:
                        continue
                    self.game.players[ev.details['id']].tank.set_pos(ev.details['pos'])
                    self.game.players[ev.details['id']].tank.set_rot(ev.details['rot'])
                    self.game.players[ev.details['id']].tank.forward()
                elif ev.details['type'] == "reverse":
                    if ev.details['id'] == self.game_logic.local_player.player_id:
                        continue
                    self.game.players[ev.details['id']].tank.set_pos(ev.details['pos'])
                    self.game.players[ev.details['id']].tank.set_rot(ev.details['rot'])
                    self.game.players[ev.details['id']].tank.reverse()
                elif ev.details['type'] == "stop":
                    if ev.details['id'] == self.game_logic.local_player.player_id:
                        continue
                    self.game.players[ev.details['id']].tank.set_pos(ev.details['pos'])
                    self.game.players[ev.details['id']].tank.set_rot(ev.details['rot'])
                    self.game.players[ev.details['id']].tank.stop()
                elif ev.details['type'] == "tur_rot":
                    if ev.details['id'] == self.game_logic.local_player.player_id:
                        continue
                    self.game.players[ev.details['id']].tank.set_pos(ev.details['pos'])
                    self.game.players[ev.details['id']].tank.set_rot(ev.details['rot'])
                    self.game.players[ev.details['id']].tank.turret.set_rot(ev.details['tRot'])
                elif ev.details['type'] == "shoot":
                    if ev.details['id'] == self.game_logic.local_player.player_id:
                        continue
                    self.game.players[ev.details['id']].tank.set_pos(ev.details['pos'])
                    self.game.players[ev.details['id']].tank.set_rot(ev.details['rot'])
                    self.game.players[ev.details['id']].tank.shoot(ev.details['misc']['target'])
                elif ev.details['type'] == "round_end":
                    print ev.details
                    self.game_logic.loop_quit = True
                elif ev.details['type'] == "tank_hit":
                    self.game.players[ev.details['misc']['target']].tank.hit(5, ev.details['id'])
                elif ev.details['type'] == "tank_die":
                    self.game.players[ev.details['misc']['killer']].award_kill()
                    for id in ev.details['misc']['assists']:
                        self.game.players[id].award_assist()
                    self.game.players[ev.details['id']].add_death()
                    self.game.players[ev.details['id']].tank.die()
        if len(self.user_events):
            if self.game.config.host == False: #if we're not the host, we're just sending our updates to the host
                update = cPickle.dumps(self.user_events)
                update_len = len(update)
                resend = True
                while resend:
                    sent = self.sock.sendto(update, self.game.config.game_host)
                    if not sent < update_len:
                        resend = False
            else:
                update = cPickle.dumps(self.user_events)
                update_len = len(update)
                for p in self.game.players:
                    resend = True
                    while resend:
                        play = self.game.players[p]
                        sent = self.sock.sendto(update, play.addr)
                        if not sent < update_len:
                            resend = False
                         """
        
    def connect(self, ev_type, callback):
        if not self.event_bindings.has_key(ev_type):
            self.event_bindings[ev_type] = []
        
        self.event_bindings[ev_type].append(callback)
